"use strict"

module.exports = function(sequelize, DataTypes) {
  var _       = require('lodash')
    , debug   = require('debug')('qywx-api-models')
    , bcrypt  = require('bcrypt-as-promised')
    , shortid = require("shortid")
    , SALT_WORK_FACTOR = process.env.X_MODELS_IDENTITY_SALT_WORK_FACTOR || 10;


  var CorpWechatAuthRequest = sequelize.define("CorpWechatAuthRequest", {
    state: {
      type: DataTypes.STRING(128)
      , allowNull: false
      , unique: true
    }
    ,corpId: {
      type: DataTypes.STRING(128)
      , allowNull: false
    }
    ,userType: {
      type: DataTypes.STRING(20)
      ,allowNull: false
      ,defaultValue: 'admin'
    }
    ,returnUrl: {
      type: DataTypes.STRING(2048)
      ,allowNull: false
    }
    ,referer: {
      type: DataTypes.STRING(2048)
      ,allowNull: true
    }
  }, {
    classMethods: {
      associate: function(models){

      }
      ,generateState: function(corpId, userType, returnUrl, referer){
        return this.create({
          state: shortid.generate(32)
          ,corpId: corpId
          ,userType: userType
          ,returnUrl: returnUrl
          ,referer: referer
        });
      }
    },
    instanceMethods: {

    }
});

  var hashStateHook = function(instance, options, cb) {
    if (!instance.changed('state')) return cb(null);
    // generate a salt
    bcrypt.genSalt(SALT_WORK_FACTOR)
        .then(function(salt) {
          // hash the password using our new salt
          //We don't need to persist the SALT because it has already been incorprated into the hash
          // http://stackoverflow.com/questions/277044/do-i-need-to-store-the-salt-with-bcrypt
          return bcrypt.hash(instance.state, salt);
        })
        .then(function(hash) {
          instance.set('state', hash);
          return cb(null, options);
        })
        .catch(function(err){
          return cb(err);
        });
  };

  CorpWechatAuthRequest.beforeCreate(hashStateHook);

  return CorpWechatAuthRequest;
};
